#ifdef RT_USE_OLD_CONN_WRAP

#include "RtBase.h"
#include "RtCnPdu.h"
#if !defined (_NEW_PROTO_TP)


///////////////////////////////////////////
//class CRtCnPduBase
///////////////////////////////////////////
CRtCnPduBase::CRtCnPduBase(BYTE byType)
{
	m_byType = byType;
	
	//RT_ASSERTE(GetFixLength(m_byType) > 0);//Ensure a valid PDU Type
}

CRtCnPduBase::~CRtCnPduBase()
{
	m_byType = CS_PDU_TYPE_HEAD;
}
	
void CRtCnPduBase::Decode(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtByteStreamIntel bs(mb);

	bs >> m_byType;

	//RT_ASSERTE(GetFixLength(m_byType) > 0);//Ensure a valid PDU Type
}

void CRtCnPduBase::Encode(CRtMessageBlock& mb)	//mb << m_xx
{
	CRtByteStreamIntel bs(mb);

	bs << m_byType;
}

DWORD CRtCnPduBase::GetFixLength(BYTE byType, BOOL bNeedACK)
{
#if 1
	switch(byType)
	{
	case CS_PDU_TYPE_DATA_START:
	case CS_PDU_TYPE_DATA_NORMAL:
		return bNeedACK ? 9 : 5;
	case CS_PDU_TYPE_HEAD:
		return 1;
	case CS_PDU_TYPE_CONN_REQ:
	case CS_PDU_TYPE_CONN_RESP:
		return 8;
	case CS_PDU_TYPE_DISCONN:
		return 3;
	case CS_PDU_TYPE_KEEPALIVE:
		return 5;
	case CS_PDU_TYPE_RTT:
		return 5;
	default:
		RT_ERROR_TRACE("CRtCnPduBase::GetFixLength(BYTE byType, BOOL bNeedACK), Invalid PDU type, byType = " << byType);
		return 0;
	}
#else
	if(byType == CS_PDU_TYPE_DATA_START || byType == CS_PDU_TYPE_DATA_NORMAL)
	{
		return bNeedACK ? 9 : 5;
	}
	else if(byType == CS_PDU_TYPE_HEAD)
		return 1;//PDU Head
	else if(byType == CS_PDU_TYPE_CONN_REQ || byType == CS_PDU_TYPE_CONN_RESP)
		return 8;
	else if(byType == CS_PDU_TYPE_DISCONN)
		return 3;
	else if(byType == CS_PDU_TYPE_KEEPALIVE)
		return 5;
	else if(byType == CS_PDU_TYPE_RTT)
		return 5;
	else
	{
		RT_ERROR_TRACE("CRtCnPduBase::GetFixLength(BYTE byType, BOOL bNeedACK), Invalid PDU type, byType = " << byType);
		return 0;
	}
#endif
}

DWORD CRtCnPduBase::GetFixLength()
{
	return CRtCnPduBase::GetFixLength(m_byType, TRUE);
}

BYTE CRtCnPduBase::GetType()
{
	return m_byType;
}
///////////////////////////////////////////
//class CRtCnPduConnReqResp
///////////////////////////////////////////
CRtCnPduConnReqResp::CRtCnPduConnReqResp(DWORD dwACK, WORD wConTag, BYTE byType, BYTE byConnType) : CRtCnPduBase(byType)
{
	m_dwACK = dwACK;
	m_wConTag = wConTag;
	m_byConnType = byConnType;
}

CRtCnPduConnReqResp::~CRtCnPduConnReqResp()
{
	m_dwACK = 0;
	m_wConTag = 0;
}

void CRtCnPduConnReqResp::Decode(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtCnPduBase::Decode(mb);

	CRtByteStreamIntel bs(mb);

	bs >> m_dwACK;
	bs >> m_wConTag;
	bs >> m_byConnType;
}

void CRtCnPduConnReqResp::Encode(CRtMessageBlock& mb)	//mb << m_xx
{
	CRtCnPduBase::Encode(mb);

	CRtByteStreamIntel bs(mb);

	bs << m_dwACK;
	bs << m_wConTag;
	bs << m_byConnType;
}

DWORD CRtCnPduConnReqResp::GetACK()
{
	return m_dwACK;
}

WORD CRtCnPduConnReqResp::GetConTag()
{
	return m_wConTag;
}

BYTE CRtCnPduConnReqResp::GetConnType()
{
	return m_byConnType;
}

///////////////////////////////////////////
//class CRtCnPduSendItem
///////////////////////////////////////////
CRtCnPduSendItem::CRtCnPduSendItem(
							   BOOL bNeedACK,
							   DWORD dwACK, 
							   BYTE byType, 
							   DWORD dwDataLen, 
							   CRtMessageBlock *pData) : CRtCnPduBase(byType)
{
	m_dwACK = dwACK;
	m_dwDataLen = dwDataLen;
	m_pmbData = pData;

	m_dwSeqStart = 0;
	m_dwSeqEnd = 0;
	m_pNextPDU = NULL;

	m_bNeedACK = bNeedACK;
}

CRtCnPduSendItem::~CRtCnPduSendItem()
{
	m_dwACK = 0;
	m_dwDataLen = 0;
	if(m_pmbData)
	{
		m_pmbData->DestroyChained();
		m_pmbData = NULL;
	}

	m_dwSeqStart = 0;
	m_dwSeqEnd = 0;
	m_pNextPDU = NULL;
}

void CRtCnPduSendItem::Decode (CRtMessageBlock& mb) 
{ 
	CRtCnPduBase::Decode(mb); 
}	

void CRtCnPduSendItem::Encode (CRtMessageBlock& mb) 
{ 
	CRtCnPduBase::Encode(mb); 
}

void CRtCnPduSendItem::SetACK(DWORD dwACK) 
{ 
	m_dwACK = dwACK; 
}

DWORD CRtCnPduSendItem::GetACK() 
{ 
	return m_dwACK; 
}

DWORD CRtCnPduSendItem::GetDataLen() 
{ 
	return m_dwDataLen; 
}

CRtMessageBlock* CRtCnPduSendItem::GetData() 
{ 
	return m_pmbData; 
}

void CRtCnPduSendItem::SetSeqStart(DWORD dwSeqStart) 
{
	if(m_byType == CS_PDU_TYPE_DATA_START || m_byType == CS_PDU_TYPE_DATA_NORMAL)
	{
		m_dwSeqStart = dwSeqStart;
		m_dwSeqEnd = m_dwSeqStart + (m_dwDataLen + GetFixLength()) - 1;
	}
	else
	{
		RT_ERROR_TRACE("CRtCnPduSendItem::SetSeqStart, Only Data PDU can be set Seq#");
	}
}

DWORD CRtCnPduSendItem::GetSeqStart()
{
	return m_dwSeqStart;
}

DWORD CRtCnPduSendItem::GetSeqEnd()
{
	return m_dwSeqEnd;
}

void CRtCnPduSendItem::SetNext(CRtCnPduSendItem *pNextPDU) 
{ 
	m_pNextPDU = pNextPDU; 
}

CRtCnPduSendItem* CRtCnPduSendItem::GetNext()
{
	return m_pNextPDU;
}

DWORD CRtCnPduSendItem::GetFixLength()
{
	return CRtCnPduBase::GetFixLength(m_byType, m_bNeedACK);
}

///////////////////////////////////////////
//class CRtCnPduDisconn
///////////////////////////////////////////
CRtCnPduDisconn::CRtCnPduDisconn(WORD wReason, BYTE byType) 
	: CRtCnPduSendItem(TRUE, 0, byType, 0, NULL)
{
	m_wReason = wReason;
}

CRtCnPduDisconn::~CRtCnPduDisconn()
{
	m_wReason = 0;
}

void CRtCnPduDisconn::Decode(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtCnPduSendItem::Decode(mb);

	CRtByteStreamIntel bs(mb);

	bs >> m_wReason;
}

void CRtCnPduDisconn::Encode(CRtMessageBlock& mb)	//mb << m_xx
{
	CRtCnPduSendItem::Encode(mb);

	CRtByteStreamIntel bs(mb);

	bs << m_wReason;
}

WORD CRtCnPduDisconn::GetReason()
{
	return m_wReason;
}

///////////////////////////////////////////
//class CRtCnPduKeepAlive
///////////////////////////////////////////
CRtCnPduKeepAlive::CRtCnPduKeepAlive(DWORD dwACK, BYTE byType) 
	: CRtCnPduSendItem(TRUE, dwACK, byType, 0, NULL)
{
}

CRtCnPduKeepAlive::~CRtCnPduKeepAlive()
{
}

void CRtCnPduKeepAlive::Decode(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtCnPduSendItem::Decode(mb);

	CRtByteStreamIntel bs(mb);

	bs >> m_dwACK;
}

void CRtCnPduKeepAlive::Encode(CRtMessageBlock& mb)	//mb << m_xx
{
	CRtCnPduSendItem::Encode(mb);

	CRtByteStreamIntel bs(mb);

	bs << m_dwACK;
}

///////////////////////////////////////////
//class CRtCnPduData
///////////////////////////////////////////
CRtCnPduData::CRtCnPduData(BOOL bNeedACK, DWORD dwACK, DWORD dwDataLen, BYTE byType, CRtMessageBlock *pData) 
	: CRtCnPduSendItem(bNeedACK, dwACK, byType, dwDataLen, pData)
{
}

CRtCnPduData::~CRtCnPduData()
{
}

void CRtCnPduData::Decode(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtCnPduSendItem::Decode(mb);

	CRtByteStreamIntel bs(mb);

	if(m_bNeedACK)
		bs >> m_dwACK;
	
	bs >> m_dwDataLen;

	RT_ASSERTE(m_pmbData == NULL);
	RT_ASSERTE(mb.GetChainedLength() >= m_dwDataLen);
	
	if(mb.GetChainedLength() == m_dwDataLen)
	{
		m_pmbData = mb.DuplicateChained();
		mb.AdvanceChainedReadPtr(m_dwDataLen);
	}
	else
	{
		RT_INFO_TRACE("CRtCnPduData::Decode(), need Disjoint mb.");
		CRtMessageBlock *pTmp = mb.Disjoint(m_dwDataLen);
		m_pmbData = mb.DuplicateChained();
		mb.AdvanceChainedReadPtr(m_dwDataLen);
		mb.Append(pTmp);
	}
}

void CRtCnPduData::Encode(CRtMessageBlock& mb)	//mb << m_xx
{
	CRtCnPduSendItem::Encode(mb);

	CRtByteStreamIntel bs(mb);

	if(m_bNeedACK)
		bs << m_dwACK;
	
	bs << m_dwDataLen;

	RT_ASSERTE(m_pmbData != NULL);
	
	mb.Append(m_pmbData);
}

void CRtCnPduData::DecodeWithOutData(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtCnPduSendItem::Decode(mb);

	CRtByteStreamIntel bs(mb);

	if(m_bNeedACK)
		bs >> m_dwACK;

	bs >> m_dwDataLen;
}

void CRtCnPduData::EncodeWithOutData(CRtMessageBlock& mb)	//mb >> m_xx
{
	CRtCnPduSendItem::Encode(mb);

	CRtByteStreamIntel bs(mb);

	if(m_bNeedACK)
		bs << m_dwACK;

	bs << m_dwDataLen;
}

CRtCnPduRtt::CRtCnPduRtt(DWORD inTimestamp)
: CRtCnPduBase(CS_PDU_TYPE_RTT)
, m_timestamp(inTimestamp)
{
}

CRtCnPduRtt::~CRtCnPduRtt()
{
}

void CRtCnPduRtt::Decode(CRtMessageBlock& mb)
{
	CRtCnPduBase::Decode(mb);

	CRtByteStreamIntel bs(mb);
	bs >> m_timestamp;
}

void CRtCnPduRtt::Encode(CRtMessageBlock& mb)
{
	CRtCnPduBase::Encode(mb);

	CRtByteStreamIntel bs(mb);
	bs << m_timestamp;
}

#endif

#endif // RT_USE_OLD_CONN_WRAP
